/*
 * BooleanVector.hpp
 *
 * Copyright 2012 Fabian Wenzelmann
 *
 * This file is part of Recognition-Procedures-for-Boolean-Functions.
 *
 * Recognition-Procedures-for-Boolean-Functions is free software: you
 * can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Recognition-Procedures-for-Boolean-Functions is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Recognition-Procedures-for-Boolean-Functions.
 *
 * If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef BOOLEANVECTOR_HPP_
#define BOOLEANVECTOR_HPP_

#include <stdarg.h>

#include <iostream>
#include <string>
#include <vector>

#include "bfr/Clause.hpp"

namespace bfr {

/**
 * A Boolean vector is a vector that contains only Boolean values.
 *
 * For example \f$X = (0, 1, 0, 0, 1)\f$ is a Boolean vector.
 */
class BooleanVector {

    public:
        typedef std::vector<bool>::const_iterator const_iterator;
        typedef std::vector<bool>::iterator iterator;

        BooleanVector();
        explicit BooleanVector(size_t initialSize, bool val=false);
        BooleanVector(const BooleanVector &other);
        explicit BooleanVector(const std::vector<bool> &vec);

        ~BooleanVector();

        inline const_iterator begin() const;
        inline const_iterator end() const;

        inline iterator begin();
        inline iterator end();

        inline size_t size() const;

        inline BooleanVector& operator =(const BooleanVector &other);

        inline bool operator[](size_t index) const;
        inline std::_Bit_reference operator[](size_t index);

        inline void push_back(bool val);

        void append(size_t num, ...);

        // comment: delete it
        // throw
        Clause *getHull(const BooleanVector &other) const;

        std::string asString() const;

        bool operator ==(const BooleanVector &other) const;
        bool operator !=(const BooleanVector &other) const;

        friend std::ostream& operator<<(std::ostream& os,
                                        const BooleanVector &bv) {
            bool first = true;
            os << '(';
            for (BooleanVector::const_iterator it = bv.begin();
                 it != bv.end();
                 it++) {
                if (first)
                    first = false;
                else {
                    os << ", ";
                }
                os << *it;
            }
            os << ')';
            return os;
        }

    private:
        std::vector<bool> point;

};


// definiton of some inline methods
BooleanVector::const_iterator BooleanVector::begin() const {
    return point.begin();
}

BooleanVector::const_iterator BooleanVector::end() const {
    return point.end();
}

BooleanVector::iterator BooleanVector::begin() {
    return point.begin();
}

BooleanVector::iterator BooleanVector::end() {
    return point.end();
}

size_t BooleanVector::size() const {
    return point.size();
}

BooleanVector& BooleanVector::operator =(const BooleanVector &other) {
    point = other.point;
    return *this;
}

bool BooleanVector::operator [](size_t index) const {
    return point[index];
}

std::_Bit_reference BooleanVector::operator [](size_t index) {
    return point[index];
}

void BooleanVector::push_back(bool val) {
    point.push_back(val);
}

} // namespace bfr

#endif  // BOOLEANVECTOR_HPP_
